<!DOCTYPE html>
<html lang="zh-cn">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">




<title>数据库事务 | Miles`s</title>

<link rel="stylesheet" href="https://mada.gitee.io/notes//css/styles.css">

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" 
integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>


<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/zenburn.min.css" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js" integrity="sha256-/BfiIkHlHoVihZdc6TFuj7MmJ0TWcWsMXkeDFwhi0zw=" crossorigin="anonymous"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script src="https://mada.gitee.io/notes//js/highlight.js"></script>






<div class="container">
    <nav class="navbar level">
      <div class="navbar-brand">
          <a class="nav-item" href="https://mada.gitee.io/notes/"><h1 class="title is-3">Miles`s</h1></a>
      </div>           
      <div class="navbar-menu has-text-centered is-active">
          <div class="navbar-end is-centered">
              
           </div>
      </div>
    </nav>
  </div>
<div class="container">
  <h2 class="subtitle is-6">July 29, 2016</h2>
  <h1 class="subtitle is-size-4-mobile is-size-3-desktop">数据库事务</h1>
  <div class="content">
    

<h3 id="数据库事务隔离级别">数据库事务隔离级别</h3>

<p>按隔离级别从低高，数据库可能出现以下错误（失去原子性、一致性的错误）：</p>

<ul>
<li>lost update ：两个事务一起更新一个行，第二个事务放弃了（在第一个事务提交之后），导致两个修改都丢失。这发生在不实现锁的系统中。并发事务不隔离。</li>
<li>dirty read：一个事务读到另一个还未提交的事务的更改。这很危险，因为第二个事务最后可能被回滚，这时第一个事务读到的更改是无效的。</li>
<li>unrepeatable read：一个事务读两次行，但结果不同。可能是有另外的事务在两次读之间修改并提交了事务。</li>
<li>unrepeatable read的一个特例是second lost updates。两个事务都读到一行，第一个事务修改并提交，然后第二个事务修改并提交。第一个事务的更改就丢失了。</li>
<li>phantom read：一个事务查询两次，第二次查询的结果集包含第一次查询时不可见的结果或行被删除。该问题由两次查询之间有另外线程插入或删除行导致。</li>
</ul>

<p>按对上述问题的允许程度，事务隔离级别从低到高分以下几种（有ANSI SQL标准定义）：</p>

<ul>
<li>read uncommitted：允许脏读的但不允许丢失更新的系统的隔离级别是read uncommitted。如果有未提交的事务已经向行写数据，则不能有另外的事务向（同一）行写数据。但任何事务都允许读任何行。数据库管理系统可以用（行级）排他写锁（注意是排他写锁，不是排它锁！）实现该隔离级别。</li>
<li>read committed：允许不可重复读，但不允许脏读的隔离级别是read committed。该级别可以由共享读锁和排他写锁实现。读线程不能阻塞其他线程访问（包括写），但未提交的写锁阻塞其他线程访问行（读也不行）。</li>
<li>可重复读，不允许不可重复读和脏读，但幻读可能发生。读事务会阻塞写事务，但不阻塞其他读事务。写事务阻塞所有事务。</li>
<li>序列化的隔离级别最高。好像事务序列化执行，没有并发。使用行级别的锁无法实现序列化。但There must instead be some other mechanism that prevents a newly inserted row from becoming visible to a transaction that has already executed a query that would return the row.</li>
</ul>

  </div>
</div>
<div class="container has-text-centered">
    
</div>

<div class="container has-text-centered">
  
</div>
<section class="section">
  <div class="container has-text-centered">
    <p></p>
  </div>
</section>


